package cn.com.headfree.locator;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.util.StringUtils;

import com.gta.edu.sdk.util.RedisClusterUtil;

import cn.com.headfree.server.service.IServerItemService;
import cn.com.headfree.vo.ZuulRouteVo;
import io.netty.util.internal.StringUtil;
import net.sf.json.JSONArray;

public class CustomRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
	public final static Logger logger = LoggerFactory.getLogger(CustomRouteLocator.class);

	private ZuulProperties properties;

	private String redisZuulRouteItem;

	private IServerItemService serverItemService;

	public CustomRouteLocator(String servletPath, ZuulProperties properties, String redisZuulRouteItem,
			IServerItemService serverItemService) {
		super(servletPath, properties);
		this.properties = properties;
		this.redisZuulRouteItem = redisZuulRouteItem;
		this.serverItemService = serverItemService;
		logger.info("servletPath:{}", servletPath);
	}

	@Override
	public void refresh() {
		doRefresh();
	}

	@Override
	protected Map<String, ZuulRoute> locateRoutes() {
		LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<String, ZuulRoute>();
		// 从application.properties中加载路由信息
		routesMap.putAll(super.locateRoutes());
		// 从db中加载路由信息
		routesMap.putAll(locateRoutesFromDB());
		// 优化一下配置
		LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();
		for (Map.Entry<String, ZuulRoute> entry : routesMap.entrySet()) {
			String path = entry.getKey();
			// Prepend with slash if not already present.
			if (!path.startsWith("/")) {
				path = "/" + path;
			}
			if (StringUtils.hasText(this.properties.getPrefix())) {
				path = this.properties.getPrefix() + path;
				if (!path.startsWith("/")) {
					path = "/" + path;
				}
			}
			values.put(path, entry.getValue());
		}
		return values;
	}

	private List<ZuulRouteVo> getRouteVos() {
		String zuulRouteStr = RedisClusterUtil.getInstance().getString(redisZuulRouteItem);
		if (StringUtils.isEmpty(zuulRouteStr)) {
			this.serverItemService.refresh();
			zuulRouteStr = RedisClusterUtil.getInstance().getString(redisZuulRouteItem);
		}
		if (StringUtils.isEmpty(zuulRouteStr)) {
			logger.warn("动态路由信息为空，请进行配置加载。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
		} else {
			JSONArray array = JSONArray.fromObject(zuulRouteStr);
			List<ZuulRouteVo> voList = JSONArray.toList(array, ZuulRouteVo.class);
			return voList;
		}
		return null;
	}

	private Map<String, ZuulRoute> locateRoutesFromDB() {
		Map<String, ZuulRoute> routes = new LinkedHashMap<>();
		List<ZuulRouteVo> results = this.getRouteVos();
		if (results != null) {
			for (ZuulRouteVo result : results) {
				if (org.apache.commons.lang3.StringUtils.isBlank(result.getPath())) {
					continue;
				}
				ZuulRoute zuulRoute = new ZuulRoute();
				try {
					org.springframework.beans.BeanUtils.copyProperties(result, zuulRoute);
				} catch (Exception e) {
					logger.error("=============load zuul route info from db with error==============", e);
				}
				if (StringUtil.isNullOrEmpty(result.getApiName())) {
					zuulRoute.setServiceId(null);
					zuulRoute.setStripPrefix(true);
					zuulRoute.setRetryable(false);
				}
				routes.put(zuulRoute.getPath(), zuulRoute);
			}
		}
		return routes;
	}
}
